//
//  File_System_Manager.h
//  LearningOops
//
//  Created by Swetha Patnala on 4/14/13.
//  Copyright (c) 2013 Swetha Patnala. All rights reserved.
//

#ifndef __LearningOops__File_System_Manager__
#define __LearningOops__File_System_Manager__

#define NUM_OF_INODES 125
#define NUM_OF_DATABLOCKS 8064
#define DATABLOCK_SIZE 4096

#include "Inode.h"
#include <string>
#include<vector>
#include "Disk.h"

using namespace std;

#include <iostream>

typedef struct {
    char* file_system_name;
    int num_of_inodes;
    int num_of_datablocks;
    int num_of_unallocated_inodes;
    int num_of_unallocated_datablocks;
    int block_number_of_superblock ;
    int inode_counter;
    int datablock_counter;
    int first_block_of_inode ;
    int first_block_of_data ;
    char* magic_number;
} super_block_structure;



class File_System_Manager {
    
    
    
private:
    static File_System_Manager* Instance;
    super_block_structure* super_block;
    File_System_Manager();
    int inode_bitmap[NUM_OF_INODES+1];
    int data_bitmap[NUM_OF_DATABLOCKS+1];
    //File_System_Manager(const File_System_Manager& orig);
    Inode* inode_array[NUM_OF_INODES+1];
    char* datablock_array[NUM_OF_DATABLOCKS+1];
    
    
public:
    
    ~File_System_Manager();
    static File_System_Manager* getInstance();
    void printSuperBlock();
    int decrement_num_of_unallocated_inodes();
    int decrement_unallocated_datablock_num(int num_of_blocks);
    int increment_inodecounter();
    int increment_datablock_num(int num_of_blocks);
    int get_inodecounter();
    bool is_inode_full();
    int assignValueToInodeBitmap(int set_inode_bitmap);
    int assignValueToDataBitmap(int data_bitmap_num);
    int increment_datablock_counter();
    void printInodeBitMap();
    void printDataBitMap();
    int getFreeBitFromInodeBitmap();
    int getFreeDataBitFromDataBitmap();
    Inode* createNewInode(int count ,char* name);
    char* getInodeArrayName(int count );
    Inode* getInodeInfo(int count);
    int allocateDataBlocksToTheFile(int data_block_num);
    void deallocateDataBlocksToTheFile(int datablock_num);
    int writeDataBlock(int datablock_address , void* buf);
    int freeInode(int inodeNum);
    void printDataOftheFile(int inode_num);
    
    
    int increment_num_of_unallocated_inodes();
    
    int increment_num_of_unallocated_datablocks();
    int decrement_inode_counter();
    
    int decrement_datablock_counter();
    
    
    
    int make_fs(char* fileSystem);
    int mount_fs(char* fileSystem);
    int unmount_fs(char* fileSystem);
    
    
};



#endif /* defined(__LearningOops__File_System_Manager__) */
